﻿
//for IE6 IE7
//考慮在此直接取用Qi.Element以取代
function parseElement(el){ //把Element類別的成員複製到HTML element內
	var IEunder7 = document.all && ! document.documentMode;
	if (IEunder7){
		if (typeof el == 'object' && el.nodeType && el.nodeType==1){
			for (var k in window.Element.prototype){
				if(!el[k]) el[k] = window.Element.prototype[k];
			}
		}else{
			//nodetype != 1
		}
	}
	return el;
}

function $(elId){
	var el = document.getElementById(elId);
	el = parseElement(el);
	//alert(el.fireEvent);
	return el;
}
Qi.Element = function(){
	//"Cannot convert WrappedNative to function
	//var args = Array.prototype.slice.call(arguments);
	//var tagName = args.shift();
	//return Qi.Element.create(tagName,args);
};

Qi.Element.create = function(tagName,options){
	var el = document.createElement(tagName);
	el = parseElement(el);//for IE6 IE7
	for (var k in options){
		if (typeof k == 'string'){
			var lowerK = k.toLowerCase();
			var v = options[k];
			switch(lowerK){
				case 'class':
					el.clsaaName = v;
					break;
				case 'for':
					el.htmlFor = v;
					break;
				case 'styles':
					for (var s in v){
						el[s.camelCase()] = v;
					}
					break;
				case 'attributes':
					for (var s in v){
						el[s] = v;
					}
					break;
				default:
					el[lowerK] = v;
					break;
			}
		}
	}
	return el;
};
var loopMax = 5;
var looper = 5;
Qi.Element.prototype = {
	getType: function(){
		return 'element';
	}
	
	//1. IE8已內建。
	//2. 當Element不存在時，於建構前已刪掉fireEvent，理論上IE6與IE7只會採用自身的fireEvent方法
	,fireEvent:function(evtName){ 
		if (evtName.substr(0,2)=='On') evtName = evtName.substr(2);
		var e = document.createEvent("HTMLEvents");  
		e.initEvent(evtName, true, false);  
		this.dispatchEvent(e);
		return this;
	}
	,storage: function(){
		return Qi.loadStorage(this.id);
	}
	,getStorage: function(){
		return Qi.loadStorage(this.id);
	}
	,store: function(type, value){
		Qi.saveStorage(this.id, type, value);
	}
	,retrieve: function(type,defaultValue){
		var value = Qi.loadStorage(this.id)[type];
		return (defaultValue != undefined && value == undefined)?defaultValue: value;
	}
	,addEvent: function(event, method){
		var storage = this.getStorage();
		var events = storage.events;
		if (!events) events = {};
		if (!events[event]){
			events[event] = [];
		}else{
			//避免附加相同的事件
			for (var i=0,len=events[event].length;i<len;i++){
				if (events[event][i].matrix == method) return this;
			}
		}
		var boundMethod = method.bind(this);
		
		var evt = {
			handler: boundMethod
			, matrix: method
			, fn: function(e){ //IE only
				var event = e|| window.event;
				evt.handler(event);
			}
		}

		events[event].push(evt);
		this.store('events', events);

		if(this.addEventListener) {
			this.addEventListener(event,evt.handler,false);
		}else if(this.attachEvent){
			this.attachEvent("on"+event,evt.fn);
		}
		return this;
	}

	,removeEvent: function(event, method){
		var storage = this.getStorage();
		var events = storage.events;
		if (!events) return;

		if (method == null){
			
			if (events[event]){
				while (events[event].length > 0){
					this.removeEvent(event,events[event][0].handler);
				}
				Qi.removeMember(events,event);
				this.store('events', events);
			}

			return this;
		}

		if(this.removeEventListener) this.removeEventListener(event,method,false);
		else if(this.detachEvent){
			//this.detachEvent("on"+event,this[event+method]);
			//this[event+method]=null;
			//this["e"+event+method]=null;
			var _method;
			for (var i=0,len=events[event].length;i<len;i++){
				if (events[event][i].handler == method){
					_method = events[event][i].fn;
					break;
				}
			}
			this.detachEvent("on"+event,_method);
		}
		if (events[event]){
			var newEventList = [];
			for (var i=0,len=events[event].length;i<len;i++){
				if (events[event][i].handler != method) newEventList.push(events[event][i]);
			}
			events[event] = newEventList;
		}
		
		this.store('events', events);
		
		return this;
	}
	
	,getEvents: function(){
		var storage = this.getStorage();
		return storage.events;
	}
	
	,addEvents: function(options){
		for (var k in options){
			if (legalEvents.indexOf(k) >=0) this.addEvent(k,options[k]);
		}
		return this;
	}
	,removeEvents: function(){
		for (var i=0,len=arguments.length;i<len;i++){
			if (legalEvents.indexOf(arguments[i]) >=0) this.removeEvent(arguments[i]);
		}
		return this;
	}
	
	,hasClassName: function(className){
		var classNames = this.className.split(' ');
		return classNames.indexOf(className)>=0;
	}

	,getClassNames: function(){
		var classNames = this.className.split(' ');
		var cleanClassNames = [];
		classNames.each(function(item){
			if (item.trim()!='')cleanClassNames.push(item.trim());
		});
		return cleanClassNames;
	}

	,addClassName: function(className){
		var classNames = this.className.split(' ');
		if (classNames.indexOf(className)<0){
			classNames.push(className);
			this.className = classNames.join(' ');
		}
	}

	,removeClassName: function(className){
		var classNames = this.className.split(' ');
		if (classNames.indexOf(className)>=0){
			this.className = classNames.remove(className).join(' ');
		}
	}

	,addClassNames: function(){
		var mother = this;
		var args = Array.prototype.slice.call(arguments);
		args.each(function(item){
			mother.addClassName(item);
		});
	}
	,removeClassNames: function(){
		var mother = this;
		var args = Array.prototype.slice.call(arguments);
		args.each(function(item){
			mother.removeClassName(item);
		});
	}	
	,parsePropertiesToCssText : function(){
		var s = this.properties.style;
		var styles = [];
		for (var k in s){
			//var style = k+':'+s[k]+';';
			styles.push(k+':'+s[k]);
		}
		return styles.join(';');
	}
	,applyStyles: function(){
		this.cssText = this.parsePropertiesToCssText();
	}
	,getStyle: function(property){
		
		var cssClasses = this.getClassNames();
		cssClasses.each(function(item,i){
			cssClasses[i] = '.' + item;
		});
		var currentStyles = [];
		var classes = document.styleSheets[0].rules || document.styleSheets[0].cssRules
			for(var x=0;x<classes.length;x++) {
			if(cssClasses.indexOf(classes[x].selectorText)>0) {
				currentStyles.push((classes[x].cssText)?classes[x].cssText:classes[x].style.cssText);
				//(classes[x].cssText) ? alert(classes[x].cssText) : alert(classes[x].style.cssText);
			}
		}

		return currentStyles.join('; ');
		return this.style[property.camelCase()];
	}
	,setStyle: function(property, value){
		property = property.camelCase();
		this.style[property] = value;
		return this;
	}
	,removeStyle: function(property){
		this.style[property.camelCase()] = '';
		return this;
	}
	,setStyles: function(options){
		for (var k in options){
			this.setStyle(k,options[k]);
		}
		return this;
	}
	,removeStyles: function(){
		for (var i=0,item;item = arguments[i];i++){
			this.removeStyle(item);
		}
		return this;
	}	
	,setOpacity: function(opacity){
		if (Qi.browser.engine.name == 'trident'){
			this.setStyle('filter', (opacity == 1) ? '' : 'alpha(opacity=' + opacity * 100 + ')');
		}
		this.style.opacity = opacity;
		this.store('opacity', opacity);
		return this;
	}
	,getOpacity: function(value){
		return this.retrieve('opacity', 1);
	}
	,fadeIn: function(){
	}
	,fadeOut: function(){
	}
};

function parseCssText(cssText){
	var properties = {'style':[]};
	var cssStyles = cssText.split(';');
	for (var i=0,len=cssStyles.length;i<len;i++){
		var cssStyle = cssStyles[i];
		if (cssStyle.indexOf(':')==0)continue;
		var css = cssStyle.split(':');
		var cssName = css[0];
		if (cssName.length==0)continue;
		var cssValue = css.length>1?css[1].trim() : '';
		var property = {};
		var dashIndex = cssName.lastIndexOf('-');
		if (dashIndex>=0){
			propertyName = cssName.substr(0,dashIndex).trim();
			propertyType = cssName.substr(dashIndex+1).trim();
			if (!properties['style'][propertyName]) properties['style'][propertyName] = {};
			properties['style'][propertyName][propertyType] = cssValue;
		}else{
		}
	}
	echo(properties);
	return properties;
}

var css = {
	group:{
		direction:['top','right','bottom','left']
		,border:['style','color','width']
		,font:['family','size','weight']
	}
	,assign:{
		direction: ['border','padding','margin']
		,border: ['border']
		,font: ['font']
	}

}


/*
Qi.Element.prototype.create = function(tagName, options){
	var el = document.createElement(tagName);
	return $(el);
}
*/

var legalEvents = [
	'click','dblclick'
	,'mouseover','mouseout','mousedown','mouseup','mousemove'
	,'keyup','keydown','keypress' //opera don't support onkeydown
	,'abort','focus','blur','change','error'
	,'reset','resize','select','submit'
	,'load','unload'
	,'domready'
];


var mouseKeyboard = [
	'altKey','shiftKey','ctrlKey','metaKey'
	,'button','clientX','clientY','screenX','screenY'
	,'relatedTarget' //not for IE
];

function Events(){
	this.list = [];
	var list = this.list;
	this.add = function(evt){
		list.push(evt);
	}
}



//dom ready for IE============
(function (){
  //check IE's proprietary DOM members
  if(!document.uniqueID && document.expando) return; 
  //you can create any tagName, even customTag like <document:ready />
  var tempNode = document.createElement('document:ready');
  (function(){  
      try {
        //wait until document.readyState === 'complete';
        if(document.readyState != 'complete') return setTimeout(arguments.callee, 0);
        //see if it throws errors until after ondocumentready
        tempNode.doScroll('left');
        //call your function which catch window.onDocumentReady
        //alert('window.onDocumentReady()');
        //relaese some memory, if possible
        tempNode = null;
      }catch (err){
        setTimeout(arguments.callee, 100);
      }
  })();   
})();
//==================


Qi.Style = {
	parse: function(cssText){
		var stylePart = csstext.split(';');
		var styles = {};
		stylePart.each(function(styleText){
			var data = styleText.split(':');
			if (data.length==2&&data[0]!='') styles[data[0]] = data[1];
		});
		return styles;
	}
	,stringify: function(styles){
		var output = [];
		for (var k in styles){
			output.push(k+':'+styles[k]);
		}
		return output.join(';')
	}
};


(function(){
	var __element = window.Element;
	if (__element == undefined) {//IE6 IE7
		//考慮以parseElement取代此段
		window.Element =  function(){};
		window.Element.constructor = new Qi.Element();
		//window.Element.prototype.constructor = __element;
		window.Element.prototype = Qi.Element.prototype;

	}else{//IE8 firefox safari opera chrome...
		
		for (var k in Qi.Element.prototype){
			if(!__element.prototype[k])__element.prototype[k] = Qi.Element.prototype[k];
		}
	}

})();
